package com.duck.duckchatbackend.controller;

import java.io.IOException;
import java.util.List;

import com.duck.duckchatbackend.annotation.GlobalInterceptor;
import com.duck.duckchatbackend.entity.dto.TokenUserInfoDto;
import com.duck.duckchatbackend.entity.enums.GroupStatusEnum;
import com.duck.duckchatbackend.entity.enums.ResponseCodeEnum;
import com.duck.duckchatbackend.entity.enums.UserContactStatusEnum;
import com.duck.duckchatbackend.entity.po.UserContact;
import com.duck.duckchatbackend.entity.query.GroupInfoQuery;
import com.duck.duckchatbackend.entity.po.GroupInfo;
import com.duck.duckchatbackend.entity.query.UserContactQuery;
import com.duck.duckchatbackend.entity.vo.GroupInfoVO;
import com.duck.duckchatbackend.entity.vo.ResponseVO;
import com.duck.duckchatbackend.exception.BusinessException;
import com.duck.duckchatbackend.service.GroupInfoService;
import com.duck.duckchatbackend.service.UserContactService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;

/**
 * Controller
 */
@RestController("groupInfoController")
@RequestMapping("/group")
public class GroupInfoController extends ABaseController {
    @Resource
    private GroupInfoService groupInfoService;
    @Resource
    private UserContactService userContactService;

    /**
     * 保存群组信息
     *
     * @param request HTTP请求对象，用于获取请求头等信息
     * @param groupId 群组ID，唯一标识一个群组
     * @param groupName 群组名称，不能为空
     * @param groupNotice 群组公告，用于向群组成员传达重要信息
     * @param joinType 加入群组的方式，不能为空，决定了新成员如何加入群组
     * @param avatarFile 群组头像文件，允许为空，用于上传群组的头像
     * @param avatarCover 群组封面文件，允许为空，用于上传群组的封面图片
     * @return 返回一个ResponseVO对象，包含执行结果信息
     * @throws IOException 如果文件上传过程中发生读写错误
     */
    @RequestMapping("/saveGroup")
    @GlobalInterceptor
    @Validated
    public ResponseVO saveGroup(

            HttpServletRequest request,
            String groupId,
            @NotEmpty String groupName,
            String groupNotice,
            @NotNull Integer joinType,
            MultipartFile avatarFile,
            MultipartFile avatarCover) throws IOException {

        // 从请求中获取用户信息，用于确定当前操作用户
        TokenUserInfoDto tokenUserInfoDto = getTokenUserInfo(request);
        // 创建群组信息对象，用于存储群组的相关信息
        GroupInfo groupInfo = new GroupInfo();
        groupInfo.setGroupId(groupId);
        groupInfo.setGroupName(groupName);
        groupInfo.setGroupNotice(groupNotice);
        // 设置群组的所有者为当前用户
        groupInfo.setGroupOwnerId(tokenUserInfoDto.getUserId());
        groupInfo.setJoinType(joinType);
        // 调用服务层方法保存群组信息，包括处理上传的文件
        this.groupInfoService.saveGroup(groupInfo, avatarFile, avatarCover);

        // 返回成功响应，不包含额外数据
        return getSuccessResponseVO(null);
    }
	/**
	 * 加载当前用户拥有的小组信息
	 *
	 * @param request HTTP请求对象，用于获取用户请求信息
	 * @return 返回一个包含用户小组信息列表的ResponseVO对象
	 */
	@RequestMapping("/loadMyGroup")
	@GlobalInterceptor
	@Validated
	public ResponseVO loadMyGroup(HttpServletRequest request){
	   // 从请求中获取用户信息
	   TokenUserInfoDto tokenUserInfoDto = getTokenUserInfo(request);
	   // 创建一个查询对象用于后续查询小组信息
	   GroupInfoQuery groupInfoQuery = new GroupInfoQuery();
	   // 设置查询条件为当前用户的用户ID
	   groupInfoQuery.setGroupOwnerId(tokenUserInfoDto.getUserId());
	   // 调用服务层方法，根据查询条件获取小组信息列表
	   List<GroupInfo> groupInfoList = this.groupInfoService.findListByParam(groupInfoQuery);
	   // 返回一个成功的响应对象，包含小组信息列表
	   return getSuccessResponseVO(groupInfoList);
	}


    /**
     * 获取群组信息
     *
     * @param request HTTP请求对象，用于获取请求头等信息
     * @param groupId 群组ID，用于查询群组信息，不能为空
     * @return ResponseVO 包含群组信息的响应对象
     */
    @RequestMapping("/getGroupInfo")
    @GlobalInterceptor
    public ResponseVO getGroupInfo(HttpServletRequest request, @NotEmpty String groupId) {
        // 调用公共方法获取群组详细信息
        GroupInfo groupInfo =  getGroupDetailCommon(request,groupId);

        // 创建用户联系人查询对象
        UserContactQuery userContactQuery = new UserContactQuery();
        // 设置联系人ID为群组ID，用于查询群组成员数量
        userContactQuery.setContactId(groupId);

        // 调用服务方法，根据查询条件统计群组成员数量
        Integer memberCount = this.userContactService.findCountByParam(userContactQuery);

        // 设置群组成员数量到群组信息对象中
        groupInfo.setMemberCount(memberCount);

        // 返回包含群组信息的成功响应对象
        return getSuccessResponseVO(groupInfo);
    }

    private GroupInfo getGroupDetailCommon(HttpServletRequest request,String groupId){
        TokenUserInfoDto tokenUserInfoDto = getTokenUserInfo(request);
        // 判断当前用户是否在该群组中
        UserContact userContact = this.userContactService.getUserContactByUserIdAndContactId(tokenUserInfoDto.getUserId(), groupId);
        if(null == userContact||!UserContactStatusEnum.FRIEND.getStatus().equals(userContact.getStatus())){
            throw new BusinessException("你不在群聊或者群聊不存在或已解散");
        }
        GroupInfo groupInfo = this.groupInfoService.getGroupInfoByGroupId(groupId);
        if(null==groupInfo||!GroupStatusEnum.NORMAL.getStatus().equals(groupInfo.getStatus())){
            throw  new BusinessException("群聊不存在或已解散");
        }
        return  groupInfo;
    }


    /**
     * 根据群组ID获取群组信息和成员信息，用于聊天场景
     *
     * @param request HTTP请求对象，用于获取请求相关数据
     * @param groupId 群组ID，用于标识特定的群组，不能为空
     * @return 返回包含群组信息和成员信息的ResponseVO对象
     */
    @RequestMapping("/getGroupInfo4Chat")
    @GlobalInterceptor
    public ResponseVO getGroupInfo4Chat(HttpServletRequest request, @NotEmpty String groupId) {
        // 获取群组详细信息
        GroupInfo groupInfo =  getGroupDetailCommon(request,groupId);

        // 创建用户联系人查询对象
        UserContactQuery userContactQuery = new UserContactQuery();

        // 设置联系人ID为群组ID，用于查询群组成员
        userContactQuery.setContactId(groupId);
        // 设置查询用户信息，以便获取成员的详细信息
        userContactQuery.setQueryUserInfo(true);
        // 设置排序方式为按创建时间升序，以保持成员列表的时间顺序
        userContactQuery.setOrderBy("create_time asc");
        // 设置联系人状态为好友，以过滤非好友成员
        userContactQuery.setStatus(UserContactStatusEnum.FRIEND.getStatus());
        // 根据查询条件获取用户联系人列表，即群组成员列表
        List<UserContact> userContactList = this.userContactService.findListByParam(userContactQuery);

        // 创建群组信息视图对象
        GroupInfoVO groupInfoVO = new GroupInfoVO();
        // 设置群组信息
        groupInfoVO.setGroupInfo(groupInfo);
        // 设置群组成员列表
        groupInfoVO.setUserContactList(userContactList);

        // 返回包含群组信息和成员信息的成功响应
        return getSuccessResponseVO(groupInfoVO);
    }
}